package id.mankel.commons.security.session;

import id.mankel.commons.util.MkDates;

import java.util.Locale;
import java.util.Optional;
import java.util.stream.Stream;

/**
 * @author Mankel
 */
public class ThreadVars {

    // TODO use InheritableThreadLocal
    private static final ThreadLocal<String> ACCESS_TOKEN = new ThreadLocal<>();
    private static final ThreadLocal<Locale> LOCALE = new ThreadLocal<>();
    /**
     * Time zone offset, in minutes.
     */
    private static final ThreadLocal<Integer> TIME_ZONE_OFFSET = new ThreadLocal<>();

    /**
     * Sets all thread vars.
     * @param accessToken
     * @param language
     * @param timeZone
     */
    public static void setAll(String accessToken, String language, String timeZone) {
        setAccessToken(accessToken);
        setLocale(language);
        setTimeZoneOffset(timeZone);
    }

    /**
     * Removes thread vars.
     */
    public static void removeAll() {
        Stream.of(ACCESS_TOKEN, LOCALE, TIME_ZONE_OFFSET).forEach(ThreadLocal::remove);
    }

    public static String getAccessToken() {
        return ACCESS_TOKEN.get();
    }
    public static Locale getLocale() {
        return Optional.ofNullable(LOCALE.get()).orElse(Locale.SIMPLIFIED_CHINESE);
    }

    public static int getTimeZoneOffset() {
        return Optional.ofNullable(TIME_ZONE_OFFSET.get()).orElse(MkDates.DEFAULT_TIME_ZONE_OFFSET_IN_MINUTE);
    }


    // ==================================================
    // private

    /**
     * @param language navigator.language
     * @return
     */
    private static Locale getLocaleByLanguage(String language) {
        return Locale.US.toLanguageTag().equalsIgnoreCase(language) ? Locale.US : Locale.SIMPLIFIED_CHINESE;
    }

    private static void setAccessToken(String accessToken) {
        ACCESS_TOKEN.set(accessToken);
    }

    private static void setLocale(String language) {
        LOCALE.set(getLocaleByLanguage(language));
    }

    private static void setTimeZoneOffset(String timeZoneOffset) {
        try {
            TIME_ZONE_OFFSET.set(Integer.parseInt(timeZoneOffset));
        } catch (Exception e) {
            TIME_ZONE_OFFSET.set(MkDates.DEFAULT_TIME_ZONE_OFFSET_IN_MINUTE);
        }
    }

}
